import time
import numpy as np
import torch 
from torch.autograd import Variable
import torch.nn.functional as F

class GoMap:
    def __init__(self,len1):
        self.maplen = len1
        self.map = torch.zeros([len1,len1])
        self.qimap = torch.zeros([len1,len1])
        self.turn = -1
        self.notpoint =[-1,-1]
        #bf
        self.bfmap = self.map.clone()
        self.bfturn = self.turn
        #qipu
        self.qipu = []
        
    def luozi(self,x,y,zhi):
        #beifeng
        self.bfturn = self.turn
        self.bfmap = self.map.clone()
        #change chara
        self.turn = -self.turn
        #1hei -1bai 0pass
        #return -:wrong, 1:ok
        if zhi==0:
            print('pass...')
            self.turn = -self.turn
            self.qipu.append([x,y,zhi])
            return 2
        if zhi!=self.turn:
            print('one can not play twice...')
            self.turn = -self.turn
            return -1
        if not((x>=0)&(y>=0)&(x<self.maplen)&(y<self.maplen)):
            print('out of the map...')
            self.turn = -self.turn
            return -2
        if self.map[x,y]!=0:
            #print('the place already has one chess...')
            self.turn = -self.turn
            return -3
        #suppose the chess is on the map
        self.map[x,y] = zhi
        #calulate the qi of the chess
        tzs = self.tizi(x,y,zhi)
        if tzs>0:
            self.qipu.append([x,y,zhi])
            return 1
        elif tzs==-1:
            print('dajie. you can not do that')
            self.bk()
            return -5
        else:
            if self.qi(x,y,zhi):
                self.zeroqimap()
                self.qipu.append([x,y,zhi])
                return 1
                #do nothing
        #return false
        self.map[x,y] = 0
        self.turn = -self.turn
        return -4
        
    def qi(self,x,y,zhi):
        if self.map[x,y]!= zhi:
            return -1
        #print(x,y)
        self.qimap[x,y]=1
        myqi = 0
        xl = x-1
        xr = x+1
        yl = y-1
        yr = y+1
        if xl>=0:
            if self.map[xl,y]==0:
                myqi += 1
            elif (self.map[xl,y]==zhi)&(self.qimap[xl,y]==0):
                myqi += self.qi(xl,y,zhi)
        if xr<self.maplen:
            if self.map[xr,y]==0:
                myqi += 1
            elif (self.map[xr,y]==zhi)&(self.qimap[xr,y]==0):
                myqi += self.qi(xl,y,zhi)
        if yl>=0:
            if self.map[x,yl]==0:
                myqi += 1
            elif (self.map[x,yl]==zhi)&(self.qimap[x,yl]==0):
                myqi += self.qi(x,yl,zhi)
        if yr<self.maplen:
            if self.map[x,yr]==0:
                myqi += 1
            elif (self.map[x,yr]==zhi)&(self.qimap[x,yr]==0):
                myqi += self.qi(x,yr,zhi)
        return myqi
    
    def tizi(self,x,y,zhi):
        #print(x,y)
        flag = 0
        xl = x-1
        xr = x+1
        yl = y-1
        yr = y+1
        delepoint=[]
        if xl>=0:
            self.zeroqimap()
            if self.qi(xl,y,-zhi)==0:
                #print(x,yl,-zhi,self.qi(xl,y,-zhi))
                flag += self.tiziqimap(delepoint)
                self.zeroqimap()
        if xr<self.maplen:
            self.zeroqimap()
            if self.qi(xr,y,-zhi)==0:
                #print(x,yl,-zhi,self.qi(xr,y,-zhi))
                flag += self.tiziqimap(delepoint)
                self.zeroqimap()
        if yl>=0:
            self.zeroqimap()
            if self.qi(x,yl,-zhi)==0:
                #print(x,yl,-zhi,self.qi(x,yl,-zhi))
                flag += self.tiziqimap(delepoint)
                self.zeroqimap()
        if yr<self.maplen:
            self.zeroqimap()
            if self.qi(x,yr,-zhi)==0:
                #print(x,yl,-zhi,self.qi(x,yr,-zhi))
                flag += self.tiziqimap(delepoint)
                self.zeroqimap()
        #dajie chuli
        if flag==1:
            #print(delepoint,self.notporint)
            if (delepoint[0]==self.notpoint):
                return -1
            self.notpoint =[x,y]
        else:
            self.notpoint =[-1,-1]
        return flag
            
        
    def tiziqimap(self,delepoint):
        sumt = 0
        for i in range(self.maplen):
            for j in range(self.maplen):
                if self.qimap[i,j]==1:
                    sumt +=1
                    self.map[i,j]=0
                    #print('tizi:',i,j)
                    delepoint.append([i,j])
        return sumt
        
    def zeroqimap(self):
        self.qimap = torch.zeros([self.maplen,self.maplen])
    
    def bk(self):
        self.map = self.bfmap.clone()
        self.turn = self.bfturn
        
    def returnmap(self):
        #print(self.map)
        return self.map

    def xspanduan(self):
        a = torch.zeros([self.maplen,self.maplen])
        for i in range(self.maplen):
            for j in range(self.maplen):
                a[i,j]=50*self.map[i,j]
        b = torch.zeros([self.maplen,self.maplen])
        for t in range(3):
            for i in range(self.maplen):
                for j in range(self.maplen):
                    if a[i,j]>0:
                        if i>0: 
                            b[i-1,j] += 1
                        if i+1<self.maplen: 
                            b[i+1,j] += 1
                        if j>0: 
                            b[i,j-1] += 1
                        if j+1<self.maplen: 
                            b[i,j+1] += 1
                    elif a[i,j]<0:
                        if i>0: 
                            b[i-1,j] -= 1
                        if i+1<self.maplen: 
                            b[i+1,j] -= 1
                        if j>0: 
                            b[i,j-1] -= 1
                        if j+1<self.maplen: 
                            b[i,j+1] -= 1
            a = a + b
        return a
    
    def shengfu(self):
        a = self.xspanduan();
        black = 0
        white = 0
        for i in range(self.maplen):
            for j in range(self.maplen):
                if a[i,j]>0:
                    black+=1
                if a[i,j]<0:
                    white+=1
        if black>white:
            return 1
        else:
            return -1
                    
    def renew(self):
        self.maplen = self.maplen
        self.map = torch.zeros([self.maplen,self.maplen])
        self.qimap = torch.zeros([self.maplen,self.maplen])
        self.turn = -1
        self.notpoint =[-1,-1]
        self.bfmap = self.map.clone()
        self.bfturn = self.turn
        self.qipu = []
        
    def loadpuzi(self,puzi):
        self.renew()
        for i in puzi:
            #print(i)
            self.luozi(i[0],i[1],i[2])
        #print(self.qipu)
        #print(self.map)
        